/***********************************************************************//**
 * @file	: lpc17xx_can.h
 * @brief	: Contains all macro definitions and function prototypes
 * 				support for CAN firmware library on LPC17xx
 * @version	: 1.0
 * @date	: 1.June.2009
 * @author	: NguyenCao
 **************************************************************************
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 **************************************************************************/

#ifndef LPC17XX_CAN_H_
#define LPC17XX_CAN_H_

#include "LPC17xx.h"
#include "lpc_types.h"


#ifdef __cplusplus
extern "C"
{
#endif

#define ID_11	1
#define MAX_HW_FULLCAN_OBJ 		64
#define MAX_SW_FULLCAN_OBJ 		32
/****************************** PRIVATE MACROS ******************************/
/** @addtogroup PRIVATE_MACROS
 * @{
 */


/** @defgroup CAN_PINSEL
 * @{
 */
/* Pin Configuration selection must be defined in structure following:
 * - Port Number,
 * - Pin Number,
 * - Function Number,
 * - Pin Mode,
 * - Open Drain
 */

/** CAN function pin selection group 0*/
#define CAN_PINSEL_RD1_P0_0		{0, 0, 1, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

#define CAN_PINSEL_TD1_P0_1		{0, 1, 1, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

#define CAN_PINSEL_RD2_P0_4		{0, 4, 2, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

#define CAN_PINSEL_TD2_P0_5		{0, 5, 2, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

/** CAN function pin selection group 1*/
#define CAN_PINSEL_RD1_P0_21	{0, 21, 3, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

#define CAN_PINSEL_TD1_P0_22	{0, 22, 3, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

#define CAN_PINSEL_RD2_P2_7		{2, 7, 1, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

#define CAN_PINSEL_TD2_P2_8		{2, 8, 1, \
								PINSEL_PINMODE_PULLUP, \
								PINSEL_PINMODE_NORMAL}

/* Max number of pin on each pin function */
#define CAN_MAX_RD1_PIN		(2)
#define CAN_MAX_TD1_PIN		(2)

#define CAN_MAX_RD2_PIN		(2)
#define CAN_MAX_TD2_PIN		(2)

/**
 * @}
 */
/*********************************************************************//**
 * Macro defines for CAN Acceptance Filter register
 **********************************************************************/
/** @defgroup CAN_REGISTER_BIT_DEFINITION
 * @{
 */
/** CAN Reset mode */
#define CAN_MOD_RM			((uint32_t)(1))
/** CAN Listen Only Mode */
#define CAN_MOD_LOM			((uint32_t)(1<<1))
/** CAN Self Test mode */
#define CAN_MOD_STM			((uint32_t)(1<<2))
/** CAN Transmit Priority mode */
#define CAN_MOD_TPM			((uint32_t)(1<<3))
/** CAN Sleep mode */
#define CAN_MOD_SM			((uint32_t)(1<<4))
/** CAN Receive Polarity mode */
#define CAN_MOD_RPM			((uint32_t)(1<<5))
/** CAN Test mode */
#define CAN_MOD_TM			((uint32_t)(1<<7))
/*********************************************************************//**
 * Macro defines for CAN Command Register
 **********************************************************************/
/** CAN Transmission Request */
#define CAN_CMR_TR			((uint32_t)(1))
/** CAN Abort Transmission */
#define CAN_CMR_AT			((uint32_t)(1<<1))
/** CAN Release Receive Buffer */
#define CAN_CMR_RRB			((uint32_t)(1<<2))
/** CAN Clear Data Overrun */
#define CAN_CMR_CDO			((uint32_t)(1<<3))
/** CAN Self Reception Request */
#define CAN_CMR_SRR			((uint32_t)(1<<4))
/** CAN Select Tx Buffer 1 */
#define CAN_CMR_STB1		((uint32_t)(1<<5))
/** CAN Select Tx Buffer 2 */
#define CAN_CMR_STB2		((uint32_t)(1<<6))
/** CAN Select Tx Buffer 3 */
#define CAN_CMR_STB3		((uint32_t)(1<<7))

/*********************************************************************//**
 * Macro defines for CAN Global Status Register
 **********************************************************************/
/** CAN Receive Buffer Status */
#define CAN_GSR_RBS			((uint32_t)(1))
/** CAN Data Overrun Status */
#define CAN_GSR_DOS			((uint32_t)(1<<1))
/** CAN Transmit Buffer Status */
#define CAN_GSR_TBS			((uint32_t)(1<<2))
/** CAN Transmit Complete Status */
#define CAN_GSR_TCS			((uint32_t)(1<<3))
/** CAN Receive Status */
#define CAN_GSR_RS			((uint32_t)(1<<4))
/** CAN Transmit Status */
#define CAN_GSR_TS			((uint32_t)(1<<5))
/** CAN Error Status */
#define CAN_GSR_ES			((uint32_t)(1<<6))
/** CAN Bus Status */
#define CAN_GSR_BS			((uint32_t)(1<<7))
/** CAN Current value of the Rx Error Counter */
#define CAN_GSR_RXERR(n)	((uint32_t)((n&0xFF)<<16))
/** CAN Current value of the Tx Error Counter */
#define CAN_GSR_TXERR(n)	((uint32_t)(n&0xFF)<<24))

/*********************************************************************//**
 * Macro defines for CAN Interrupt and Capture Register
 **********************************************************************/
/** CAN Receive Interrupt */
#define CAN_ICR_RI			((uint32_t)(1))
/** CAN Transmit Interrupt 1 */
#define CAN_ICR_TI1			((uint32_t)(1<<1))
/** CAN Error Warning Interrupt */
#define CAN_ICR_EI			((uint32_t)(1<<2))
/** CAN Data Overrun Interrupt */
#define CAN_ICR_DOI			((uint32_t)(1<<3))
/** CAN Wake-Up Interrupt */
#define CAN_ICR_WUI			((uint32_t)(1<<4))
/** CAN Error Passive Interrupt */
#define CAN_ICR_EPI			((uint32_t)(1<<5))
/** CAN Arbitration Lost Interrupt */
#define CAN_ICR_ALI			((uint32_t)(1<<6))
/** CAN Bus Error Interrupt */
#define CAN_ICR_BEI			((uint32_t)(1<<7))
/** CAN ID Ready Interrupt */
#define CAN_ICR_IDI			((uint32_t)(1<<8))
/** CAN Transmit Interrupt 2 */
#define CAN_ICR_TI2			((uint32_t)(1<<9))
/** CAN Transmit Interrupt 3 */
#define CAN_ICR_TI3			((uint32_t)(1<<10))
/** CAN Error Code Capture */
#define CAN_ICR_ERRBIT(n)	((uint32_t)((n&0x1F)<<16))
/** CAN Error Direction */
#define CAN_ICR_ERRDIR		((uint32_t)(1<<21))
/** CAN Error Capture */
#define CAN_ICR_ERRC(n)		((uint32_t)((n&0x3)<<22))
/** CAN Arbitration Lost Capture */
#define CAN_ICR_ALCBIT(n)		((uint32_t)((n&0xFF)<<24))

/*********************************************************************//**
 * Macro defines for CAN Interrupt Enable Register
 **********************************************************************/
/** CAN Receive Interrupt Enable */
#define CAN_IER_RIE			((uint32_t)(1))
/** CAN Transmit Interrupt Enable for buffer 1 */
#define CAN_IER_TIE1		((uint32_t)(1<<1))
/** CAN Error Warning Interrupt Enable */
#define CAN_IER_EIE			((uint32_t)(1<<2))
/** CAN Data Overrun Interrupt Enable */
#define CAN_IER_DOIE		((uint32_t)(1<<3))
/** CAN Wake-Up Interrupt Enable */
#define CAN_IER_WUIE		((uint32_t)(1<<4))
/** CAN Error Passive Interrupt Enable */
#define CAN_IER_EPIE		((uint32_t)(1<<5))
/** CAN Arbitration Lost Interrupt Enable */
#define CAN_IER_ALIE		((uint32_t)(1<<6))
/** CAN Bus Error Interrupt Enable */
#define CAN_IER_BEIE		((uint32_t)(1<<7))
/** CAN ID Ready Interrupt Enable */
#define CAN_IER_IDIE		((uint32_t)(1<<8))
/** CAN Transmit Enable Interrupt for Buffer 2 */
#define CAN_IER_TIE2		((uint32_t)(1<<9))
/** CAN Transmit Enable Interrupt for Buffer 3 */
#define CAN_IER_TIE3		((uint32_t)(1<<10))

/*********************************************************************//**
 * Macro defines for CAN Bus Timing Register
 **********************************************************************/
/** CAN Baudrate Prescaler */
#define CAN_BTR_BRP(n)		((uint32_t)(n&0x3FF))
/** CAN Synchronization Jump Width */
#define CAN_BTR_SJM(n)		((uint32_t)((n&0x3)<<14))
/** CAN Time Segment 1 */
#define CAN_BTR_TESG1(n)	((uint32_t)(n&0xF)<<16))
/** CAN Time Segment 2 */
#define CAN_BTR_TESG2(n)	((uint32_t)(n&0xF)<<20))
/** CAN Sampling */
#define CAN_BTR_SAM(n)		((uint32_t)(1<<23))

/*********************************************************************//**
 * Macro defines for CAN Error Warning Limit Register
 **********************************************************************/
/** CAN Error Warning Limit */
#define CAN_EWL_EWL(n)		((uint32_t)(n&0xFF))

/*********************************************************************//**
 * Macro defines for CAN Status Register
 **********************************************************************/
/** CAN Receive Buffer Status */
#define CAN_SR_RBS		((uint32_t)(1))
/** CAN Data Overrun Status */
#define CAN_SR_DOS		((uint32_t)(1<<1))
/** CAN Transmit Buffer Status 1 */
#define CAN_SR_TBS1		((uint32_t)(1<<2))
/** CAN Transmission Complete Status of Buffer 1 */
#define CAN_SR_TCS1		((uint32_t)(1<<3))
/** CAN Receive Status */
#define CAN_SR_RS		((uint32_t)(1<<4))
/** CAN Transmit Status 1 */
#define CAN_SR_TS1		((uint32_t)(1<<5))
/** CAN Error Status */
#define CAN_SR_ES		((uint32_t)(1<<6))
/** CAN Bus Status */
#define CAN_SR_BS		((uint32_t)(1<<7))
/** CAN Transmit Buffer Status 2 */
#define CAN_SR_TBS2		((uint32_t)(1<<10))
/** CAN Transmission Complete Status of Buffer 2 */
#define CAN_SR_TCS2		((uint32_t)(1<<11))
/** CAN Transmit Status 2 */
#define CAN_SR_TS2		((uint32_t)(1<<13))
/** CAN Transmit Buffer Status 2 */
#define CAN_SR_TBS3		((uint32_t)(1<<18))
/** CAN Transmission Complete Status of Buffer 2 */
#define CAN_SR_TCS3		((uint32_t)(1<<19))
/** CAN Transmit Status 2 */
#define CAN_SR_TS3		((uint32_t)(1<<21))

/*********************************************************************//**
 * Macro defines for CAN Receive Frame Status Register
 **********************************************************************/
/** CAN ID Index */
#define CAN_RFS_ID_INDEX(n)	((uint32_t)(n&0x3FF))
/** CAN Bypass */
#define CAN_RFS_BP			((uint32_t)(1<<10))
/** CAN Data Length Code */
#define CAN_RFS_DLC(n)		((uint32_t)((n&0xF)<<16)
/** CAN Remote Transmission Request */
#define CAN_RFS_RTR			((uint32_t)(1<<30))
/** CAN control 11 bit or 29 bit Identifier */
#define CAN_RFS_FF			((uint32_t)(1<<31))

/*********************************************************************//**
 * Macro defines for CAN Receive Identifier Register
 **********************************************************************/
/** CAN 11 bit Identifier */
#define CAN_RID_ID_11(n)		((uint32_t)(n&0x7FF))
/** CAN 29 bit Identifier */
#define CAN_RID_ID_29(n)		((uint32_t)(n&0x1FFFFFFF))

/*********************************************************************//**
 * Macro defines for CAN Receive Data A Register
 **********************************************************************/
/** CAN Receive Data 1 */
#define CAN_RDA_DATA1(n)		((uint32_t)(n&0xFF))
/** CAN Receive Data 2 */
#define CAN_RDA_DATA2(n)		((uint32_t)((n&0xFF)<<8))
/** CAN Receive Data 3 */
#define CAN_RDA_DATA3(n)		((uint32_t)((n&0xFF)<<16))
/** CAN Receive Data 4 */
#define CAN_RDA_DATA4(n)		((uint32_t)((n&0xFF)<<24))

/*********************************************************************//**
 * Macro defines for CAN Receive Data B Register
 **********************************************************************/
/** CAN Receive Data 5 */
#define CAN_RDB_DATA5(n)		((uint32_t)(n&0xFF))
/** CAN Receive Data 6 */
#define CAN_RDB_DATA6(n)		((uint32_t)((n&0xFF)<<8))
/** CAN Receive Data 7 */
#define CAN_RDB_DATA7(n)		((uint32_t)((n&0xFF)<<16))
/** CAN Receive Data 8 */
#define CAN_RDB_DATA8(n)		((uint32_t)((n&0xFF)<<24))

/*********************************************************************//**
 * Macro defines for CAN Transmit Frame Information Register
 **********************************************************************/
/** CAN Priority */
#define CAN_TFI_PRIO(n)			((uint32_t)(n&0xFF))
/** CAN Data Length Code */
#define CAN_TFI_DLC(n)			((uint32_t)((n&0xF)<<16))
/** CAN Remote Frame Transmission */
#define CAN_TFI_RTR				((uint32_t)(1<<30))
/** CAN control 11-bit or 29-bit Identifier */
#define CAN_TFI_FF				((uint32_t)(1<<31))

/*********************************************************************//**
 * Macro defines for CAN Transmit Identifier Register
 **********************************************************************/
/** CAN 11-bit Identifier */
#define CAN_TID_ID11(n)			((uint32_t)(n&0x7FF))
/** CAN 11-bit Identifier */
#define CAN_TID_ID29(n)			((uint32_t)(n&0x1FFFFFFF))

/*********************************************************************//**
 * Macro defines for CAN Transmit Data A Register
 **********************************************************************/
/** CAN Transmit Data 1 */
#define CAN_TDA_DATA1(n)		((uint32_t)(n&0xFF))
/** CAN Transmit Data 2 */
#define CAN_TDA_DATA2(n)		((uint32_t)((n&0xFF)<<8))
/** CAN Transmit Data 3 */
#define CAN_TDA_DATA3(n)		((uint32_t)((n&0xFF)<<16))
/** CAN Transmit Data 4 */
#define CAN_TDA_DATA4(n)		((uint32_t)((n&0xFF)<<24))

/*********************************************************************//**
 * Macro defines for CAN Transmit Data B Register
 **********************************************************************/
/** CAN Transmit Data 5 */
#define CAN_TDA_DATA5(n)		((uint32_t)(n&0xFF))
/** CAN Transmit Data 6 */
#define CAN_TDA_DATA6(n)		((uint32_t)((n&0xFF)<<8))
/** CAN Transmit Data 7 */
#define CAN_TDA_DATA7(n)		((uint32_t)((n&0xFF)<<16))
/** CAN Transmit Data 8 */
#define CAN_TDA_DATA8(n)		((uint32_t)((n&0xFF)<<24))

/*********************************************************************//**
 * Macro defines for CAN Sleep Clear Register
 **********************************************************************/
/** CAN1 Sleep mode */
#define CAN1SLEEPCLR			((uint32_t)(1<<1))
/** CAN2 Sleep Mode */
#define CAN2SLEEPCLR			((uint32_t)(1<<2))

/*********************************************************************//**
 * Macro defines for CAN Wake up Flags Register
 **********************************************************************/
/** CAN1 Sleep mode */
#define CAN_WAKEFLAGES_CAN1WAKE		((uint32_t)(1<<1))
/** CAN2 Sleep Mode */
#define CAN_WAKEFLAGES_CAN2WAKE		((uint32_t)(1<<2))

/*********************************************************************//**
 * Macro defines for Central transmit Status Register
 **********************************************************************/
/** CAN Transmit 1 */
#define CAN_TSR_TS1			((uint32_t)(1))
/** CAN Transmit 2 */
#define CAN_TSR_TS2			((uint32_t)(1<<1))
/** CAN Transmit Buffer Status 1 */
#define CAN_TSR_TBS1			((uint32_t)(1<<8))
/** CAN Transmit Buffer Status 2 */
#define CAN_TSR_TBS2			((uint32_t)(1<<9))
/** CAN Transmission Complete Status 1 */
#define CAN_TSR_TCS1			((uint32_t)(1<<16))
/** CAN Transmission Complete Status 2 */
#define CAN_TSR_TCS2			((uint32_t)(1<<17))

/*********************************************************************//**
 * Macro defines for Central Receive Status Register
 **********************************************************************/
/** CAN Receive Status 1 */
#define CAN_RSR_RS1				((uint32_t)(1))
/** CAN Receive Status 1 */
#define CAN_RSR_RS2				((uint32_t)(1<<1))
/** CAN Receive Buffer Status 1*/
#define CAN_RSR_RB1				((uint32_t)(1<<8))
/** CAN Receive Buffer Status 2*/
#define CAN_RSR_RB2				((uint32_t)(1<<9))
/** CAN Data Overrun Status 1 */
#define CAN_RSR_DOS1			((uint32_t)(1<<16))
/** CAN Data Overrun Status 1 */
#define CAN_RSR_DOS2			((uint32_t)(1<<17))

/*********************************************************************//**
 * Macro defines for Central Miscellaneous Status Register
 **********************************************************************/
/** Same CAN Error Status in CAN1GSR */
#define CAN_MSR_E1		((uint32_t)(1))
/** Same CAN Error Status in CAN2GSR */
#define CAN_MSR_E2		((uint32_t)(1<<1))
/** Same CAN Bus Status in CAN1GSR */
#define CAN_MSR_BS1		((uint32_t)(1<<8))
/** Same CAN Bus Status in CAN2GSR */
#define CAN_MSR_BS2		((uint32_t)(1<<9))

/*********************************************************************//**
 * Macro defines for Acceptance Filter Mode Register
 **********************************************************************/
/* CAN Acceptance Filter Off mode */
#define CAN_AFMR_AccOff		((uint32_t)(1))
/** CAN Acceptance File Bypass mode */
#define CAN_AFMR_AccBP		((uint32_t)(1<<1))
/** FullCAN Mode Enhancements */
#define CAN_AFMR_eFCAN		((uint32_t)(1<<2))

/*********************************************************************//**
 * Macro defines for Standard Frame Individual Start Address Register
 **********************************************************************/
/** The start address of the table of individual Standard Identifier */
#define CAN_STT_sa(n)		((uint32_t)((n&1FF)<<2))

/*********************************************************************//**
 * Macro defines for Standard Frame Group Start Address Register
 **********************************************************************/
/** The start address of the table of grouped Standard Identifier */
#define CAN_SFF_GRP_sa(n)		((uint32_t)((n&3FF)<<2))

/*********************************************************************//**
 * Macro defines for Extended Frame Start Address Register
 **********************************************************************/
/** The start address of the table of individual Extended Identifier */
#define CAN_EFF_sa(n)		((uint32_t)((n&1FF)<<2))

/*********************************************************************//**
 * Macro defines for Extended Frame Group Start Address Register
 **********************************************************************/
/** The start address of the table of grouped Extended Identifier */
#define CAN_Eff_GRP_sa(n)		((uint32_t)((n&3FF)<<2))

/*********************************************************************//**
 * Macro defines for End Of AF Table Register
 **********************************************************************/
/** The End of Table of AF LookUp Table */
#define CAN_EndofTable(n)		((uint32_t)((n&3FF)<<2))

/*********************************************************************//**
 * Macro defines for LUT Error Address Register
 **********************************************************************/
/** CAN Look-Up Table Error Address */
#define CAN_LUTerrAd(n)		((uint32_t)((n&1FF)<<2))

/*********************************************************************//**
 * Macro defines for LUT Error Register
 **********************************************************************/
/** CAN Look-Up Table Error */
#define CAN_LUTerr		((uint32_t)(1))

/*********************************************************************//**
 * Macro defines for Global FullCANInterrupt Enable Register
 **********************************************************************/
/** Global FullCANInterrupt Enable */
#define CAN_FCANIE		((uint32_t)(1))

/*********************************************************************//**
 * Macro defines for FullCAN Interrupt and Capture Register 0
 **********************************************************************/
/** FullCAN Interrupt and Capture (0-31)*/
#define CAN_FCANIC0_IntPnd(n)	((uint32_t)(1<<n))

/*********************************************************************//**
 * Macro defines for FullCAN Interrupt and Capture Register 1
 **********************************************************************/
/** FullCAN Interrupt and Capture (0-31)*/
#define CAN_FCANIC1_IntPnd(n)	((uint32_t)(1<<(n-32)))


/**************************** GLOBAL/PUBLIC TYPES ***************************/
/** @addtogroup PUBLIC_TYPES
 * @{
 */

/** @defgroup CAN_TYPES
 * @{
 */
/** CAN configuration structure */
/***********************************************************************
 * CAN device configuration commands (IOCTL commands and arguments)
 **********************************************************************/
/** CAN ID format definition */
typedef enum
{
	STD_ID_FORMAT = 0, /* Use standard ID format (11 bit ID) */
	EXT_ID_FORMAT = 1  /* Use extended ID format (29 bit ID) */
}CAN_ID_FORMAT_Type;

/** Symbolic names for type of CAN message */
typedef enum
{
	DATA_FRAME = 0, 		/* Data frame */
	REMOTE_FRAME = 1		/* Remote frame */
} CAN_FRAME_Type;

/** Type definition to hold a FullCAN message */
typedef struct
{
	uint32_t Data1;			/* Full CAN msg information */
	uint32_t DataA;			/* First 32bit CAN data */
	uint32_t DataB;			/* Second 32bit CAN data */
} FULLCAN_MSGFIELD;

/** CAN message object structure                                              */
typedef struct
{
	uint32_t id;                 /* 29 bit identifier, it depend on "format" value
								 - if format = STD_ID_FORMAT, id should be 11 bit identifier
								 - if format = EXT_ID_FORMAT, id should be 29 bit identifier*/
	uint32_t dataA;            	 /* Data field A */
	uint32_t dataB;				 /* Data field B */
	uint8_t  len;                /* Length of data field in bytes, should be:
								 - 0000b-0111b: 0-7 bytes
								 - 1xxxb: 8 bytes */
	uint8_t  format;             /* Identifier Format, should be:
								 - STD_ID_FORMAT: Standard ID - 11 bit format
								 - EXT_ID_FORMAT: Extended ID - 29 bit format*/
	uint8_t  type;               /* Remote Frame transmission, should be:
								 - DATA_FRAME: the number of data bytes called out by the DLC
								   field are send from the CANxTDA and CANxTDB registers
								 - REMOTE_FRAME: Remote Frame is sent*/
	uint8_t  Reserved;			 /* Unused - Fill it to 32-bit width */
} CAN_MSG_Type;

/** CAN Control status */
typedef enum
{
	CANCTRL_GLOBAL_STS = 0,		/* CAN Global Status */
	CANCTRL_INT_CAP,			/* CAN Interrupt and Capture */
	CANCTRL_ERR_WRN,			/* CAN Error Warning Limit */
	CANCTRL_STS					/* CAN Control Status */
} CAN_CTRL_STS_Type;

/** Central CAN status type */
typedef enum
{
	CANCR_TX_STS = 0, 			/* Central CAN Tx Status */
	CANCR_RX_STS,				/* Central CAN Rx Status */
	CANCR_MS					/* Central CAN Miscellaneous Status */
} CAN_CR_STS_Type;

/** CAN interrupt enable type */
typedef enum
{
	CANINT_RIE = 0,				/* CAN Receiver Interrupt Enable */
	CANINT_TIE1,				/* CAN Transmit Interrupt Enable */
	CANINT_EIE,					/* CAN Error Warning Interrupt Enable */
	CANINT_DOIE,				/* CAN Data Overrun Interrupt Enable */
	CANINT_WUIE,				/* CAN Wake-Up Interrupt Enable */
	CANINT_EPIE,				/* CAN Error Passive Interrupt Enable */
	CANINT_ALIE,				/* CAN Arbitration Lost Interrupt Enable */
	CANINT_BEIE,				/* CAN Bus Error Inter rupt Enable */
	CANINT_IDIE,				/* CAN ID Ready Interrupt Enable */
	CANINT_TIE2,				/* CAN Transmit Interrupt Enable for Buffer2 */
	CANINT_TIE3,				/* CAN Transmit Interrupt Enable for Buffer3 */
	CANINT_FCE					/* FullCAN Interrupt Enable */
} CAN_INT_EN_Type;

/** Acceptance Filter Mode type */
typedef enum
{
	CAN_Normal = 0,
	CAN_AccOff, 				/* Acceptance Filter Off Mode */
	CAN_AccBP,					/* Acceptance Fileter Bypass Mode */
	CAN_eFCAN					/* FullCAN Mode Enhancement */
}CAN_AFMODE_Type;

typedef enum
{
	CAN_OPERATING_MODE = 0,		/* Operating Mode */
	CAN_RESET_MODE,				/* Reset Mode */
	CAN_LISTENONLY_MODE,		/* Listen Only Mode */
	CAN_SELFTEST_MODE,			/* Seft Test Mode */
	CAN_TXPRIORITY_MODE,		/* Transmit Priority Mode */
	CAN_SLEEP_MODE,				/* Sleep Mode */
	CAN_RXPOLARITY_MODE,		/* Receive Polarity Mode */
	CAN_TEST_MODE				/* Test Mode */
}CAN_MODE_Type;

/** Error values that functions can return */
typedef enum
{
	CAN_OK = 1,                       /* No error */
	CAN_NOT_IMPLEMENTED_ERROR,        /* Function has not been implemented */
	CAN_BAUDRATE_ERROR,               /* Baudrate was not set */
	CAN_TX_BUSY_ERROR,                /* Transmitting hardware busy */
	CAN_OBJECTS_FULL_ERROR,           /* No more rx or tx objects available */
	CAN_UNEXIST_CTRL_ERROR,           /* CAN Controller does not exist */
	CAN_INIT_ERROR,					  /* CAN device has not been init */
	CAN_FULL_OBJ_NOT_RCV,			  /* Full CAN object not received */
	CAN_NOT_DATA_FRM_ERROR,			  /* Not data frame error */
	CAN_NO_RECEIVE_DATA,			  /* No have receive data available */
	CAN_AF_ENTRY_ERROR
}  CAN_ERROR;

typedef struct {
	uint8_t RD;				/** Serial Inputs, from CAN transceivers, should be:
							** For CAN1:
							- CAN_RD1_P0_0: RD pin is on P0.0
							- CAN_RD1_P0_21 : RD pin is on P0.21
							** For CAN2:
							- CAN_RD2_P0_4: RD pin is on P0.4
							- CAN_RD2_P2_7: RD pin is on P2.7
							 */
	uint8_t TD;				/** Serial Outputs, To CAN transceivers, should be:
							 ** For CAN1:
							 - CAN_TD1_P0_1: TD pin is on P0.1
							 - CAN_TD1_P0_22: TD pin is on P0.22
							 ** For CAN2:
							 - CAN_TD2_P0_5: TD pin is on P0.5
							 - CAN_TD2_P2_8: TD pin is on P2.8
							 */
	uint8_t Reserved[2];
}CAN_PinCFG_Type;

/** Struct definition for AF Lookup Table */
typedef struct
{
	uint8_t controller;
	uint8_t disable;
	uint16_t id_11;
	struct FullCAN_Entry* next;
}FullCAN_Entry;

typedef struct
{
	uint8_t controller;			/** CAN Controller, should be:
								- CAN1_CTRL: CAN1 Controller
								- CAN2_CTRL: CAN2 Controller
								*/
	uint8_t disable;			/** Disable bit, should be:
								- MSG_ENABLE: disable bit = 0
								- MSG_DISABLE: disable bit = 1
								*/
	uint16_t id_11;				/** Standard ID, should be 11-bit value */
	struct SFF_Entry* next;		/** The pointer point to next SFF_Entry */
}SFF_Entry;

typedef struct
{
	uint8_t controller1;		/** First CAN Controller, should be:
								- CAN1_CTRL: CAN1 Controller
								- CAN2_CTRL: CAN2 Controller
								*/
	uint8_t disable1;			/** First Disable bit, should be:
								- MSG_ENABLE: disable bit = 0
								- MSG_DISABLE: disable bit = 1
								*/
	uint16_t lowerID;			/** ID lower bound, should be 11-bit value */
	uint8_t controller2;		/** Second CAN Controller, should be:
								- CAN1_CTRL: CAN1 Controller
								- CAN2_CTRL: CAN2 Controller
								*/
	uint8_t disable2;			/** Second Disable bit, should be:
								- MSG_ENABLE: disable bit = 0
								- MSG_DISABLE: disable bit = 1
								*/
	uint16_t upperID;			/** ID upper bound, should be 11-bit value and
								 equal or greater than lowerID*/
	struct SFF_GPR_Entry *next; /** The pointer point to next SFF_GPR_Entry */
}SFF_GPR_Entry;

typedef struct
{
	uint8_t controller;			/** CAN Controller, should be:
								- CAN1_CTRL: CAN1 Controller
								- CAN2_CTRL: CAN2 Controller
								*/
	uint8_t Reserved[3];
	uint32_t ID_29;				/** Extend ID, shoud be 29-bit value */
	struct EFF_Entry* next;		/** The pointer point to next EFF_Entry */
}EFF_Entry;

typedef struct
{
	uint8_t controller1;		/** First CAN Controller, should be:
								- CAN1_CTRL: CAN1 Controller
								- CAN2_CTRL: CAN2 Controller
								*/
	uint8_t controller2;		/** Second Disable bit, should be:
								- MSG_ENABLE: disable bit = 0
								- MSG_DISABLE: disable bit = 1
								*/
	uint8_t Reserved2[2];
	uint32_t lowerEID;			/** Extended ID lower bound, should be 29-bit value */
	uint32_t upperEID;			/** Extended ID upper bound, should be 29-bit value */
	struct EFF_GPR_Entry* next; /** The pointer point to next EFF_GPR_Entry */
}EFF_GPR_Entry;

typedef struct
{
	FullCAN_Entry* FullCAN_Sec;   	/* The pointer point to FullCAN_Entry */
	SFF_Entry* SFF_Sec;				/* The pointer point to SFF_Entry */
	SFF_GPR_Entry* SFF_GPR_Sec;		/* The pointer point to SFF_GPR_Entry */
	EFF_Entry* EFF_Sec;				/* The pointer point EFF_Entry */
	EFF_GPR_Entry* EFF_GPR_Sec;		/* The pointer point EFF_GPR_Entry */
}AF_SectionDef;

/** CAN call-back function type definitions */
typedef void (fnCANCbs_Type)();
/**
 * @}
 */

/**
 * @}
 */

/*************************** GLOBAL/PUBLIC MACROS ***************************/
/** @addtogroup PUBLIC_MACROS
 * @{
 */

/** @defgroup I2S_MACROS
 * @{
 */

/** Macro to determine if it is valid CAN peripheral */
#define PARAM_CANx(x)			((((uint32_t*)x)==((uint32_t *)CAN1)) \
								||(((uint32_t*)x)==((uint32_t *)CAN2)))
#define PARAM_CANAFx(x)			(((uint32_t*)x)== ((uint32_t*)CANAF))
#define PARAM_CANAFRAMx(x)		(((uint32_t*)x)== (uint32_t*)CANAF_RAM)
#define PARAM_CANCRx(x)			(((uint32_t*)x)==((uint32_t*)CANCR))

/** Macro to check Data to send valid */
#define PARAM_I2S_DATA(data) 	((data>=0)&&(data <= 0xFFFFFFFF))
#define PRAM_I2S_FREQ(freq)		((freq>=16000)&&(freq <= 96000))

/** Macro to check Pin Selection value */
#define PARAM_RD1_PIN(n)		((n==CAN_RD1_P0_0)||(n==CAN_RD1_P0_21))
#define PARAM_TD1_PIN(n)		((n==CAN_TD1_P0_1)||(n==CAN_TD1_P0_22))
#define PARAM_RD2_PIN(n)		((n==CAN_RD2_P0_4)||(n==CAN_RD2_P2_7))
#define PARAM_TD2_PIN(n)		((n==CAN_TD2_P0_5)||(n==CAN_TD2_P2_8))

/** Macro to check Frame Identifier */
#define PARAM_ID_11(n)			((n>>11)==0) /*-- 11 bit --*/
#define PARAM_ID_29(n)			((n>>29)==0) /*-- 29 bit --*/

#define PARAM_DLC(n)			((n>>4)==0)  /*-- 4 bit --*/
#define PARAM_ID_FORMAT(n)		((n==STD_ID_FORMAT)||(n==EXT_ID_FORMAT))
#define PARAM_GRP_ID(x,y)		((x<=y))
#define PARAM_FRAME_TYPE(n)		((n==DATA_FRAME)||(n==REMOTE_FRAME))

/** Macro to check Control/Central Status type parameter */
#define PARAM_CTRL_STS_TYPE(n)	((n==CANCTRL_GLOBAL_STS)||(n==CANCTRL_INT_CAP) \
							    ||(n==CANCTRL_ERR_WRN)||(n==CANCTRL_STS))
#define PARAM_CR_STS_TYPE(n)	((n==CANCR_TX_STS)||(n==CANCR_RX_STS) \
							    ||(n==CANCR_MS))
/** Macro to check AF Mode type parameter */
#define PARAM_AFMODE_TYPE(n)	((n==CAN_Normal)||(n==CAN_AccOff) \
								||(n==CAN_AccBP)||(n==CAN_eFCAN))
/** Macro to check Operation Mode */
#define PARAM_MODE_TYPE(n)		((n==CAN_OPERATING_MODE)||(n==CAN_RESET_MODE) \
								||(n==CAN_LISTENONLY_MODE)||(n==CAN_SELFTEST_MODE) \
								||(n==CAN_TXPRIORITY_MODE)||(n==CAN_SLEEP_MODE) \
								||(n==CAN_RXPOLARITY_MODE)||(n==CAN_TEST_MODE))

/** Macro define for struct AF_Section parameter */
#define CAN1_CTRL				((uint8_t)(0))
#define CAN2_CTRL				((uint8_t)(1))
#define PARAM_CTRL(n)			((n==CAN1_CTRL)|(n==CAN2_CTRL))

#define MSG_ENABLE				((uint8_t)(0))
#define MSG_DISABLE				((uint8_t)(1))
#define PARAM_MSG_DISABLE(n)	((n==MSG_ENABLE)|(n==MSG_DISABLE))

/**Macro to check Interrupt Type parameter */
#define PARAM_INT_EN_TYPE(n)	((n==CANINT_RIE)||(n==CANINT_TIE1) \
								||(n==CANINT_EIE)||(n==CANINT_DOIE) \
								||(n==CANINT_WUIE)||(n==CANINT_EPIE) \
								||(n==CANINT_ALIE)||(n==CANINT_BEIE) \
								||(n==CANINT_IDIE)||(n==CANINT_TIE2) \
								||(n==CANINT_TIE3)||(n==CANINT_FCE))

/** CAN function pin selection defines */
#define CAN_RD1_P0_0		((uint8_t)(0))
#define CAN_RD1_P0_21		((uint8_t)(0))
#define CAN_TD1_P0_1		((uint8_t)(0))
#define CAN_TD1_P0_22		((uint8_t)(0))

#define CAN_RD2_P0_4		((uint8_t)(0))
#define CAN_RD2_P2_7		((uint8_t)(2))
#define CAN_TD2_P0_5		((uint8_t)(0))
#define CAN_TD2_P2_8		((uint8_t)(2))

/*********************************************************************//**
 * CAN configuration parameter defines
 **********************************************************************/

/**
 * @}
 */

/**
 * @}
 */

/************************** GLOBAL/PUBLIC FUNCTIONS *************************/
/** @addtogroup PUBLIC_FUNCTION_PROTOTYPES
 * @{
 */

/** @defgroup I2S_FUNCTIONS
 * @{
 */
void CAN_SetBaudRate (CAN_TypeDef *CANx, uint32_t baudrate);
void CAN_Init(CAN_TypeDef *CANx, uint32_t baudrate);
CAN_ERROR CAN_LoadID (CAN_TypeDef *CANx,CANAF_RAM_TypeDef* CANAFRAM,uint32_t id, CAN_ID_FORMAT_Type format);
Status CAN_SendMsg (CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg);
Status CAN_ReceiveMsg (CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg);
CAN_ERROR FCAN_ReadObj (CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg);
uint32_t CAN_GetCTRLStatus (CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg);
uint32_t CAN_GetCRStatus (CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg);
void CAN_IRQCmd (CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState);
void CAN_SetAFMode(CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFmode);
void CAN_ModeConfig(CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState);
CAN_ERROR CAN_SetupAFLUT(CANAF_TypeDef* CANAFx,CANAF_RAM_TypeDef* CANAFRAM, AF_SectionDef* AFSection);
void CAN_SetupCBS(CAN_INT_EN_Type arg,fnCANCbs_Type* pnCANCbs);
void CAN_IntHandler(CAN_TypeDef* CANx);
/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif


#endif /* LPC17XX_CAN_H_ */
